(function(root) {


    /**
     *  jQuery 特点 
     * 
     * 1. 无new 构建实例对象
     * 
     * 2. 共享原型
     * 
     * 3. extend 拓展
     * 
     */

    function jQuery() {
        /**
         *  形成死循环  
         */
        // return new jQuery()  
        return new jQuery.prototype.init()
    }
    /**
     *  重写jQuery 原型，  来实现 构建无new操作符实例 ， 将jQuery的方法放在原型上
     */
    jQuery.prototype = {
            /**
             *  构建实例对象
             */
            init: function() {

            },
            html: function() {

            },
            css: function() {

                }
                //  ...
        }
        /**
         *  简写原型 
         */
    jQuery.fn = jQuery.prototype
        /**
         *  实现原型 共享 原型
         */
    jQuery.fn.init.prototype = jQuery.fn;


    /**
     *  extend 
     * 
     * 1. 可以给任意多个对象合并
     * 
     * 2. 可以拓展jQuery本身
     * 
     * 3. 可以拓展jQuery实例方法
     */

    jQuery.extend = jQuery.fn.extend = function() {
        /**
         * 参数分为多种情况 
         * 
         * 1. 有多个参数时 
         *      1. 第一个参数为 boolean 且为true 时  则代表要进行深拷贝
         *      
         *      2. 否则第一个参数必为对象
         * 
         * 2. 只有一个参数时
         *      
         *      1. 代表着给jQuery本身 / jQuery 实例 添加拓展方法
         * 
         */
        var target = arguments[0];
        var length = arguments.length;
        var deep = false
        var i = 1;

        if (Object.prototype.toString.call(target).slice(8, -1) === 'Array') {
            deep = true;
            target = arguments[1]
            i++
        }

        if (typeof target != 'object') {
            target = {}
        }

        if (i === length) {
            target = this;
            i--
        }

        for (; i < length; i++) {
            var option = arguments[i];
            for (var name in option) {
                var copy = option[name];
                var src = target[name];
                var isArray = Object.prototype.toString.call(copy).slice(8, -1) === 'Array';
                var isObject = Object.prototype.toString.call(copy).slice(8, -1) === 'Object'
                var clone = {};
                if (deep && (isArray || isObject)) {
                    if (isArray) {
                        clone = Object.prototype.toString.call(src).slice(8, -1) === 'Array' ? src : [];
                    } else if (isObject) {
                        clone = Object.prototype.toString.call(src).slice(8, -1) === 'Object' ? src : {}
                    } else {
                        clone = src
                    }
                    target[name] = jQuery.extend(deep, clone, copy)
                } else if (copy !== undefined) {
                    target[name] = copy
                }
            }
        }

        return target
    }


    jQuery.extend({
        isPlainObject: function(data) {
            return Object.prototype.toString.call(data).slice(8, -1) === 'Object'
        },
        isFunction: function(fn) {
            return Object.prototype.toString.call(fn).slice(8, -1) === 'Function'
        },
        isArray: function(data) {
            return Object.prototype.toString.call(data).slice(8, -1) === 'Array'
        },
        isBoolean: function(data) {
            return Object.prototype.toString.call(data).slice(8, -1) === 'Boolean'
        },
    })


    //  将jQuery挂载到window（全局变量）上
    root.jQuery = root.$ = jQuery
})(this)